package com.example.myapplicationktkt2.storage

import android.content.ContentValues
import android.content.Context
import android.content.SharedPreferences
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.os.Bundle
import android.os.Environment
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.myapplicationktkt2.R
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException

/**
 * 1. 内部存储（Internal Storage）
 * 使用 openFileOutput 和 openFileInput 方法实现
 * 数据保存在应用私有目录中，其他应用无法访问
 * 示例演示了如何写入和读取文本文件
 * 2. 外部存储（External Storage）
 * 使用 getExternalFilesDir 方法实现
 * 数据保存在外部存储的应用特定目录中
 * 包含了权限检查和错误处理
 * 3. SharedPreferences
 * 使用 getSharedPreferences 方法实现
 * 适用于存储简单的键值对数据
 * 示例展示了如何保存和读取字符串数据
 * 4. SQLite数据库
 * 使用 SQLiteOpenHelper 和 SQLiteDatabase 实现
 * 创建了一个简单的数据库表用于存储数据
 * 演示了数据的插入和查询操作
 *
 */
class DataStorageDemoActivity : AppCompatActivity() {

    // 数据库相关
    private lateinit var dbHelper: DataDbHelper
    private lateinit var database: SQLiteDatabase

    // 内部存储相关控件
    private lateinit var etInternalData: EditText
    private lateinit var btnSaveInternal: Button
    private lateinit var btnLoadInternal: Button
    private lateinit var tvInternalResult: TextView

    // 外部存储相关控件
    private lateinit var etExternalData: EditText
    private lateinit var btnSaveExternal: Button
    private lateinit var btnLoadExternal: Button
    private lateinit var tvExternalResult: TextView

    // SharedPreferences相关控件
    private lateinit var etSharedPrefData: EditText
    private lateinit var btnSaveSharedPref: Button
    private lateinit var btnLoadSharedPref: Button
    private lateinit var tvSharedPrefResult: TextView

    // SQLite相关控件
    private lateinit var etSQLiteData: EditText
    private lateinit var btnSaveSQLite: Button
    private lateinit var btnLoadSQLite: Button
    private lateinit var tvSQLiteResult: TextView

    // SharedPreferences实例
    private lateinit var sharedPreferences: SharedPreferences

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_data_storage_demo)

        // 初始化视图
        initViews()

        // 初始化数据库
        dbHelper = DataDbHelper(this)
        database = dbHelper.writableDatabase

        // 初始化SharedPreferences
        sharedPreferences = getSharedPreferences("data_storage_demo", MODE_PRIVATE)

        // 设置点击事件
        setClickListeners()
    }

    private fun initViews() {
        // 内部存储控件
        etInternalData = findViewById(R.id.etInternalData)
        btnSaveInternal = findViewById(R.id.btnSaveInternal)
        btnLoadInternal = findViewById(R.id.btnLoadInternal)
        tvInternalResult = findViewById(R.id.tvInternalResult)

        // 外部存储控件
        etExternalData = findViewById(R.id.etExternalData)
        btnSaveExternal = findViewById(R.id.btnSaveExternal)
        btnLoadExternal = findViewById(R.id.btnLoadExternal)
        tvExternalResult = findViewById(R.id.tvExternalResult)

        // SharedPreferences控件
        etSharedPrefData = findViewById(R.id.etSharedPrefData)
        btnSaveSharedPref = findViewById(R.id.btnSaveSharedPref)
        btnLoadSharedPref = findViewById(R.id.btnLoadSharedPref)
        tvSharedPrefResult = findViewById(R.id.tvSharedPrefResult)

        // SQLite控件
        etSQLiteData = findViewById(R.id.etSQLiteData)
        btnSaveSQLite = findViewById(R.id.btnSaveSQLite)
        btnLoadSQLite = findViewById(R.id.btnLoadSQLite)
        tvSQLiteResult = findViewById(R.id.tvSQLiteResult)
    }

    private fun setClickListeners() {
        // 内部存储事件
        btnSaveInternal.setOnClickListener {
            saveToInternalStorage()
        }

        btnLoadInternal.setOnClickListener {
            loadFromInternalStorage()
        }

        // 外部存储事件
        btnSaveExternal.setOnClickListener {
            saveToExternalStorage()
        }

        btnLoadExternal.setOnClickListener {
            loadFromExternalStorage()
        }

        // SharedPreferences事件
        btnSaveSharedPref.setOnClickListener {
            saveToSharedPreferences()
        }

        btnLoadSharedPref.setOnClickListener {
            loadFromSharedPreferences()
        }

        // SQLite事件
        btnSaveSQLite.setOnClickListener {
            saveToSQLite()
        }

        btnLoadSQLite.setOnClickListener {
            loadFromSQLite()
        }
    }

    // 内部存储方法
    private fun saveToInternalStorage() {
        val data = etInternalData.text.toString()
        if (data.isEmpty()) {
            Toast.makeText(this, "请输入要保存的数据", Toast.LENGTH_SHORT).show()
            return
        }

        try {
            openFileOutput("internal_data.txt", MODE_PRIVATE).use { outputStream ->
                outputStream.write(data.toByteArray())
            }
            Toast.makeText(this, "内部存储保存成功", Toast.LENGTH_SHORT).show()
        } catch (e: IOException) {
            Toast.makeText(this, "保存失败: ${e.message}", Toast.LENGTH_SHORT).show()
        }
    }

    private fun loadFromInternalStorage() {
        try {
            openFileInput("internal_data.txt").use { inputStream ->
                val data = inputStream.bufferedReader().use { it.readText() }
                tvInternalResult.text = data
            }
        } catch (e: IOException) {
            Toast.makeText(this, "读取失败: ${e.message}", Toast.LENGTH_SHORT).show()
            tvInternalResult.text = ""
        }
    }

    // 外部存储方法
    private fun saveToExternalStorage() {
        val data = etExternalData.text.toString()
        if (data.isEmpty()) {
            Toast.makeText(this, "请输入要保存的数据", Toast.LENGTH_SHORT).show()
            return
        }

        if (!isExternalStorageWritable()) {
            Toast.makeText(this, "外部存储不可写", Toast.LENGTH_SHORT).show()
            return
        }

        try {
            val dir = getExternalFilesDir(null)
            val file = File(dir, "external_data.txt")
            FileOutputStream(file).use { outputStream ->
                outputStream.write(data.toByteArray())
            }
            Toast.makeText(this, "外部存储保存成功", Toast.LENGTH_SHORT).show()
        } catch (e: IOException) {
            Toast.makeText(this, "保存失败: ${e.message}", Toast.LENGTH_SHORT).show()
        }
    }

    private fun loadFromExternalStorage() {
        if (!isExternalStorageReadable()) {
            Toast.makeText(this, "外部存储不可读", Toast.LENGTH_SHORT).show()
            return
        }

        try {
            val dir = getExternalFilesDir(null)
            val file = File(dir, "external_data.txt")
            FileInputStream(file).use { inputStream ->
                val data = inputStream.bufferedReader().use { it.readText() }
                tvExternalResult.text = data
            }
        } catch (e: IOException) {
            Toast.makeText(this, "读取失败: ${e.message}", Toast.LENGTH_SHORT).show()
            tvExternalResult.text = ""
        }
    }

    // 检查外部存储是否可写
    private fun isExternalStorageWritable(): Boolean {
        return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
    }

    // 检查外部存储是否可读
    private fun isExternalStorageReadable(): Boolean {
        return Environment.getExternalStorageState() in
            setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY)
    }

    // SharedPreferences方法
    private fun saveToSharedPreferences() {
        val data = etSharedPrefData.text.toString()
        if (data.isEmpty()) {
            Toast.makeText(this, "请输入要保存的数据", Toast.LENGTH_SHORT).show()
            return
        }

        with(sharedPreferences.edit()) {
            putString("shared_pref_data", data)
            apply()
        }
        Toast.makeText(this, "SharedPreferences保存成功", Toast.LENGTH_SHORT).show()
    }

    private fun loadFromSharedPreferences() {
        val data = sharedPreferences.getString("shared_pref_data", "")
        tvSharedPrefResult.text = data
    }

    // SQLite方法
    private fun saveToSQLite() {
        val data = etSQLiteData.text.toString()
        if (data.isEmpty()) {
            Toast.makeText(this, "请输入要保存的数据", Toast.LENGTH_SHORT).show()
            return
        }

        val values = ContentValues().apply {
            put(DataDbHelper.COLUMN_DATA, data)
        }

        val newRowId = database.insert(DataDbHelper.TABLE_NAME, null, values)
        if (newRowId != -1L) {
            Toast.makeText(this, "SQLite保存成功", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this, "SQLite保存失败", Toast.LENGTH_SHORT).show()
        }
    }

    private fun loadFromSQLite() {
        val projection = arrayOf(DataDbHelper.COLUMN_DATA)

        val cursor = database.query(
            DataDbHelper.TABLE_NAME,
            projection,
            null,
            null,
            null,
            null,
            null
        )

        val dataList = mutableListOf<String>()
        while (cursor.moveToNext()) {
            val data = cursor.getString(cursor.getColumnIndexOrThrow(DataDbHelper.COLUMN_DATA))
            dataList.add(data)
        }
        cursor.close()

        tvSQLiteResult.text = dataList.joinToString("\n")
    }

    // 数据库帮助类
    class DataDbHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {

        override fun onCreate(db: SQLiteDatabase) {
            db.execSQL(SQL_CREATE_ENTRIES)
        }

        override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
            db.execSQL(SQL_DELETE_ENTRIES)
            onCreate(db)
        }

        companion object {
            const val DATABASE_VERSION = 1
            const val DATABASE_NAME = "DataStorageDemo.db"

            const val TABLE_NAME = "data_entries"
            const val COLUMN_ID = "id"
            const val COLUMN_DATA = "data"

            const val SQL_CREATE_ENTRIES =
                "CREATE TABLE $TABLE_NAME (" +
                "$COLUMN_ID INTEGER PRIMARY KEY," +
                "$COLUMN_DATA TEXT)"

            const val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS $TABLE_NAME"
        }
    }
}